import socket
import time
import struct
import threading

class MyClient:
    def __init__(self, ID, targetID, hostIP, hostAddr):
        self.running = False
        self.ID = ID
        self.targetID = targetID
        self.host = hostIP
        self.port = hostAddr
        self.hostAddr = (self.host, self.port)
        self.SockUDP = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  #UDP协议
        #self.SockUDP.bind(self.addr)
        self.loginHead = bytes([self.ID, 0, self.targetID])
        self.logoutHead = bytes([self.ID, 1])
        self.msgHead = bytes([self.ID, 2])
        self.callback = self.empty

    def empty(self, data, srcID):
        pass
        
    def login(self, callback):
        Timeout = 3
        self.callback = callback
        while Timeout:
            try:
                self.SockUDP.sendto(self.loginHead, self.hostAddr)
                HostData, HostAddr = self.SockUDP.recvfrom(1024)
            except:
                time.sleep(1)
                Timeout -= 1
                print('retry!')
            else:
                if HostData == b'ok':
                    self.running = True
                    self.thread = threading.Thread(target = self.recvThread, args=()).start()  #打开收数据的线程
                    break
                else:
                    time.sleep(1)
                    Timeout -= 1
                    print('retry!')
        if Timeout:
            print('连接服务器成功！数据传输已开启')
            return True
        else:
            print('连接服务器失败！')
            return False
            
    def send(self, data):
        if self.running:
            self.SockUDP.sendto(self.msgHead + bytes(data), self.hostAddr)
        else:
            print('未连接服务器！')

    def recvThread(self):  #接收数据线程的函数
        while self.running:
            try:
                HostData, HostAddr = self.SockUDP.recvfrom(1024)
            except:
                time.sleep(1)
                print('retry!')
            else:
                #print(HostData)
                #print(HostAddr)
                if HostData[1] == 2:
                    srcID = HostData[0]
                    Data = HostData[2:]
                    self.callback(Data, srcID)

    def close(self):
        self.SockUDP.sendto(self.logoutHead, self.hostAddr)
        self.running = False

def f(a,b):
    print(a)
    print(b)

if __name__ == '__main__':
    str1=b'\x7f\x11\x03\x40\x01\x40\x7e'
    str2=b'\x7f\x11\x03\x40\x40\x40\x7e'
    client = MyClient(1, 2, '127.0.0.1', 8083)
    client.login(f)
    while True:
        client.send(str1)
        time.sleep(1)
        client.send(str2)
        time.sleep(1)
